package com.zone.core

import android.app.Activity
import android.app.Application
import android.app.NotificationManager
import android.app.Service
import android.content.Context
import android.os.Bundle
import android.util.Log
import android.widget.PopupWindow
import com.therouter.TheRouter
import java.util.Stack
import kotlin.system.exitProcess

open class CoreApplication : Application() {
    override fun attachBaseContext(base: Context?) {
        super.attachBaseContext(base)
        coreApp = this
    }

    override fun onCreate() {
        super.onCreate()
        registerActivityLife(this)

        initRouter()
    }

    /**
     * 路由配置
     */
    private fun initRouter() {
        try {
            TheRouter.init(this)
        } catch (e: java.lang.Exception) {
            e.printStackTrace()
        }
    }


    private fun registerActivityLife(application: Application) {
        application.registerActivityLifecycleCallbacks(object : ActivityLifecycleCallbacks {
            override fun onActivityCreated(activity: Activity, bundle: Bundle?) {
                addActivity(activity)
            }

            override fun onActivityStarted(activity: Activity) {}
            override fun onActivityResumed(activity: Activity) {}
            override fun onActivityPaused(activity: Activity) {}
            override fun onActivityStopped(activity: Activity) {}
            override fun onActivitySaveInstanceState(activity: Activity, bundle: Bundle) {}
            override fun onActivityDestroyed(activity: Activity) {
                removeActivity(activity)
            }
        })
    }

    /*============================================================================================================*/

    companion object CoreApp {
        private val LOG_TAG = CoreApp::class.java.simpleName

        lateinit var coreApp: Application
        private var activityStack: Stack<Activity> = Stack()
        private var serviceStack: Stack<Service> = Stack()
        private var popupWindowStack: Stack<PopupWindow> = Stack()

        /**
         * 退出程序
         *
         * @param context
         * 指定的context
         * @since 1.0
         */
        fun appExit() {
            try {
                finishAllNotification()
                finishAllActivity()
                finishAllService()
                finishAllPopupWindow()
                dismissAllPopupWindow()
                android.os.Process.killProcess(android.os.Process.myPid())
                exitProcess(0)
            } catch (e: Exception) {
                Log.i(LOG_TAG, "App Exit Exception", e)
            }

        }

        /**
         * 清除所有通知消息
         *
         * @param context
         * 指定的context
         */
        fun finishAllNotification() {
            val mNotificationManager = coreApp
                .getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
            mNotificationManager.cancelAll()
        }

        /**
         * 销毁指定的类别的Acivtiy，可能一个activity会在应用中存在多个实例
         *
         * @param cls 指定类型的Activity
         */
        fun finishActivity(cls: Class<*>) {
            // 由于list使用iterator遍历的时候不能remove掉
            val removeList = ArrayList<Activity>()
            for (activity in activityStack) {
                if (activity.javaClass == cls) {
                    removeList.add(activity)
                    // finishActivity(activity);
                }
            }
            activityStack.removeAll(removeList)
            for (activity in removeList) {
                activity.finish()
            }
        }

        /**
         * 销毁除去此类型之外的Activity对象
         *
         * @param cls
         * 不删除指定类型的Activity实例
         */
        fun finishWithOut(cls: Class<*>) {
            // 由于list使用iterator遍历的时候不能remove掉
            val removeList = ArrayList<Activity>()
            for (activity in activityStack) {
                if (activity.javaClass != cls) {
                    removeList.add(activity)
                }
            }
            for (activity in removeList) {
                activity.finish()
            }
        }

        /**
         * 销毁除去此对象之外的Activity对象
         *
         * @param withOutActivity
         * 不删除的类型
         * @since 1.0
         */
        fun finishWithOut(withOutActivity: Activity) {
            // 由于list使用iterator遍历的时候不能remove掉
            val removeList = ArrayList<Activity>()
            for (activity in activityStack) {
                if (activity !== withOutActivity) {
                    removeList.add(activity)
                }
            }
            for (activity in removeList) {
                activity.finish()
            }
        }

        /**
         * 销毁当前应用中所有的activity
         *
         * @since 1.0
         */
        fun finishAllActivity() {
            var i = 0
            val size = activityStack.size
            while (i < size) {
                if (null != activityStack[i]) {
                    Log.d(
                        LOG_TAG,
                        "+++++++++++++++++++activityStack:" + activityStack[i].localClassName
                    )
                    activityStack[i].finish()
                }
                i++
            }
            activityStack.clear()
        }

        /**
         * 销毁当前应用中的Service
         *
         * @since 1.0
         */
        fun finishAllService() {
            var i = 0
            val size = serviceStack.size
            while (i < size) {
                if (null != serviceStack[i]) {
                    serviceStack[i].stopSelf()
                }
                i++
            }
            serviceStack.clear()
        }


        /**
         * 销毁指定的PopupWindow
         * @param popupWindow
         * 指定的popupWindow
         */
        fun finishPopupWindow(popupWindow: PopupWindow?) {
            if (popupWindow != null) {
                popupWindowStack.remove(popupWindow)
                popupWindow.dismiss()
            }
        }

        /**
         *
         * 清除所有的popupWindow
         *
         * @since 1.0
         */
        fun finishAllPopupWindow() {
            var i = 0
            val size = popupWindowStack.size
            while (i < size) {
                if (null != popupWindowStack[i]) {
                    popupWindowStack[i].dismiss()
                }
                i++
            }
            popupWindowStack.clear()
        }

        /**
         *
         * 销毁所有popupwindow
         *
         * @since 1.0
         * @author xhyin
         * @date 2014-10-21
         */
        fun dismissAllPopupWindow() {
            var i = 0
            val size = popupWindowStack.size
            while (i < size) {
                if (popupWindowStack[i] != null) {
                    Log.e(
                        LOG_TAG,
                        "+++++++++++++++++++popupWindowStack:" + (popupWindowStack[i] as PopupWindow).javaClass.simpleName
                    )
                    (popupWindowStack[i] as PopupWindow).dismiss()
                }
                i++
            }
        }

        /**
         *
         * Activity进栈
         *
         * @param activity
         * 指定的activity
         */
        @Synchronized
        fun addActivity(activity: Activity) {
            Log.d(LOG_TAG, "------------------activity:" + activity.localClassName)
            activityStack.add(activity)
        }

        /**
         * 将指定service推到Service栈中
         *
         * @param service
         * 指定的service
         */
        @Synchronized
        fun addService(service: Service) {
            Log.d(LOG_TAG, "------------------service:" + service.javaClass.simpleName)
            serviceStack.add(service)
        }

        /**
         *
         * 将指定的popupwindow推入PopupWindow栈中
         *
         * @param popupWindow
         */
        @Synchronized
        fun addPopupWindow(popupWindow: PopupWindow) {
            Log.d(LOG_TAG, "------------------popupWindow:" + popupWindow.javaClass.simpleName)
            popupWindowStack.add(popupWindow)
        }

        /**
         * 获取当前Activity（堆栈中最后一个压入的）
         *
         * @return 当前Activity
         */
        fun currentActivity(): Activity {
            return activityStack.lastElement()
        }

        /**
         * @param activity
         * 指定的activity
         */
        fun removeActivity(activity: Activity) {
            activityStack.remove(activity)
        }
    }
}